package com.feinno.urcs.group.servlet;

import com.feinno.cpim.CpimHeader;
import com.feinno.cpim.CpimMessage;
import com.feinno.sip.header.ContentType;
import com.feinno.sip.message.Content;
import com.feinno.urcs.content.Cpim;
import com.feinno.urcs.content.MimeType;
import com.feinno.urcs.content.UrcsMultipartMimeContent;
import com.feinno.urcs.group.api.GroupChatService;
import com.feinno.urcs.group.api.GroupService;
import com.feinno.urcs.group.siptask.task.GroupMessageArgs;
import com.feinno.urcs.group.siputils.URIUtils;
import com.feinno.urcs.nai.IMPU;
import com.feinno.urcs.profile.entity.ClientType;
import com.feinno.urcs.sipservlet.SipServlet;
import com.feinno.urcs.sipservlet.SipServletException;
import com.feinno.urcs.sipservlet.SipServletRequest;
import com.feinno.urcs.types.MobileNo;
import com.feinno.urcs.utils.SipHeaderUtils;
import com.feinno.util.DateUtil;
import org.helium.framework.annotations.ServiceSetter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sip.address.URI;

/**
 * PdGroupMessage
 *
 * Created by wuhao on 5/11/15.
 */
public class GroupMessageServlet extends SipServlet{
    private static final Logger LOGGER = LoggerFactory.getLogger(GroupMessageServlet.class);
    @ServiceSetter
    private GroupChatService groupChatService;
    @ServiceSetter
    private GroupService groupService;

    @Override
    protected void process(SipServletRequest sipServletRequest) throws SipServletException {
        LOGGER.info("GroupMessageServlet process Begin");
        //检查群状态
        if(!check(sipServletRequest)){
                return;
        }
        LOGGER.info("Group Page Mode Request:{}", sipServletRequest);
        GroupMessageArgs groupMessageArgs = parseMessageArgs(sipServletRequest);
        try {
            if(groupMessageArgs != null){
                groupChatService.sendText(groupMessageArgs.getGroupId(), groupMessageArgs.getFromMobile(),
                        groupMessageArgs.getContentType(), groupMessageArgs.getContent(), ClientType.APP, null, DateUtil.getUTCNow());
            }

        } catch (Exception e) {
            LOGGER.error("GroupMessageServlet SendText Error: {}", e);
        }
        sipServletRequest.sendResponse(202, "Accept");
        LOGGER.info("GroupMessageServlet process End");
    }

    /**
     *检查消息
     *
     */
    private boolean check(SipServletRequest request) {
        LOGGER.info("GroupMessageServlet check Begin");
        URI sendUri = request.getFromHeader().getAddress().getURI();
        IMPU grouper = SipHeaderUtils.getToUser(request);

        if (!grouper.toUri().isSipURI()) {
            request.sendResponse(404, "Group uri must be sip uri.");
            return false;
        }
        //检查群是否存在及其他状态
        try {
            groupService.check(MobileNo.parseFrom(URIUtils.getMobileNo(sendUri)), grouper.toUri().toString());
        } catch (Exception e) {
            LOGGER.info("GroupMessageServlet Check Mobile{}", e);
            request.sendResponse(500, "GroupMessageServlet Group Error");
            return false;
        }
        LOGGER.info("GroupMessageServlet check End");
        return true;
    }

    /**
     *解析消息体
     *
     */
    private GroupMessageArgs parseMessageArgs(SipServletRequest request){
        //the arg for return
        GroupMessageArgs groupMessageArgs = new GroupMessageArgs();
        //判断是否为状态回执
        if (isImdn(request)){
            return null;
        }
        //get the sender and grouper
        MobileNo sender = MobileNo.parseFrom(getSender(request).getUser());
        MobileNo to = MobileNo.parseFrom(getTo(request).getUser());
        int groupId = URIUtils.getGroupIdFromUri(getGroup(request).toString());
        //set entity
        groupMessageArgs.setFromMobile(sender);
        groupMessageArgs.setGroupId(groupId);
        groupMessageArgs.setToMobile(to);
        groupMessageArgs.setContent(getContent(request));
        groupMessageArgs.setContentType(getContentType(request));
        return groupMessageArgs;
    }



    /**
     * 是否为状态回执
     *
     * @param request
     * @return
     */
    public boolean isImdn(SipServletRequest request){
        boolean sign = false;
        //get the message body
        UrcsMultipartMimeContent ummc = request.getMultipartMimeContent();
        //精心处理前判断是否是CPIM的消息回执，及是否需要消息回执
        Cpim cpim = ummc.getContent(Cpim.class);
        if (cpim != null) {
            try {
                //判断是否为消息回执
                CpimHeader contentType_header = cpim.getCpimMessage().getHeader("Content-Type");
                if(MimeType.parse(contentType_header.getValue()) == MimeType.IMDN){
                    CpimMessage infx= cpim.getCpimMessage();
                    if(infx != null){
                        LOGGER.debug("return message not require send");
                        sign = true;
                    }
                }
            } catch (Exception e) {
                LOGGER.error("GroupMessageServlet parse content error {}", e);
            }
        }
        return sign;
    }

    /**
     * parse sender from request
     *
     * @param request
     * @return
     */
    protected IMPU getSender(SipServletRequest request) {
        IMPU sender = null;
        URI uri = request.getPAssertedIdentity().getAddress().getURI();
        sender = IMPU.fromUri(uri);
        return sender;
    }
    /**
     * parse to from request
     *
     * @param request
     * @return
     */
    protected  IMPU getTo(SipServletRequest request){
        IMPU impu = null;
        URI uri = request.getTo().getAddress().getURI();
        impu = IMPU.fromUri(uri);
        return impu;
    }
    /**
     * parse group from uri
     *
     * @param request
     * @return
     */
    protected URI getGroup(SipServletRequest request){
        URI uri = request.getRequestURI();
        return  uri;
    }

    /**
     * parse content from request
     *
     * @param request
     * @return
     */
    public byte[] getContent(SipServletRequest request){
        byte[] content = null;
        UrcsMultipartMimeContent ummc = request.getMultipartMimeContent();
        ContentType contentType = ummc.getContentTypeHeader();
        // 1.cpim
        Cpim cpimContent = ummc.getContent(Cpim.class);
        if (cpimContent != null) {
            content = cpimContent.getContent();
        }
        // 2.text
        Content textContent = ummc.getContent(MimeType.TextPlain);
        if (textContent != null) {
            content = cpimContent.getContent();
        }
        return content;
    }

    /**
     * parse contentType from request
     *
     * @param request
     * @return
     */
    protected String getContentType(SipServletRequest request) {
        ContentType contentType = (ContentType) request.getHeader(ContentType.NAME);
        return contentType.getMediaRange().toString();
    }

}